#include <benchmark/benchmark.h>
#include "string.h"
#include "util.h"

using namespace std;

// 从test2复制4个字符到test1
static void Bm_function_Memmove(benchmark::State &state)
{
    char test1[] = "pression buffer";
    char test2[] = "/data/data/.pulse_dir/runtime";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(memmove(test1, test2, 10));
    }
    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Strlen(benchmark::State &state)
{
    char test[] = "openharmony";

    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strlen(test));
    }
    state.SetItemsProcessed(state.iterations());
}

// 将特定的字符复制到目标前n个位置
static void Bm_function_Memset(benchmark::State &state)
{
    char test[] = "openharmony";

    for (auto _ : state)
    {
        benchmark::DoNotOptimize(memset(test, 'a', 4));
    }
    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Strcmp(benchmark::State &state)
{
    char test1[] = "openharmony";
    char test2[] = "closeharmony";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strcmp(test1, test2));
    }
    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Memcmp(benchmark::State &state)
{
    char test1[] = "openharmony";
    char test2[] = "OPENHARMONY";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(memcmp(test1, test2, 4));
    }
    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Memchr(benchmark::State &state)
{
    const char test[] = "openharmony";
    const char ch = 'n';
    const void *ret;
    for (auto _ : state)
    {
        ret = memchr(test, ch, strlen(test));
        benchmark::DoNotOptimize(ret);
    }

    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Strrchr(benchmark::State &state)
{
    const char test[] = "com.ohos.mms";
    const char ch = 'm';
    const void *ret;
    for (auto _ : state)
    {
        ret = strrchr(test, ch);
        benchmark::DoNotOptimize(ret);
    }

    state.SetItemsProcessed(state.iterations());
}
// 选定范围计算长度
static void Bm_function_Strnlen(benchmark::State &state)
{
    const char *test = "com.ohos.mms";

    for (auto _ : state)
    {
        size_t len = strnlen(test, 6);
        benchmark::DoNotOptimize(len);
    }

    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Stpncpy(benchmark::State &state)
{
    char test[] = "com.ohos.mms";
    char dest[20];
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(stpncpy(dest, test, 5));
    }

    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Bcmp(benchmark::State &state)
{
    char test1[] = {0x41, 0x42, 0x43};
    char test2[] = {0x41, 0x42, 0x44};
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(bcmp(test1, test2, 3));
    }

    state.SetItemsProcessed(state.iterations());
}

// 给定字符串中查找第一个匹配另一个指定字符串中任何字符的字符
static void Bm_function_Strpbrk(benchmark::State &state)
{
    const char test1[] = "open.harmony";
    const char test2[] = "enh";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strpbrk(test1, test2));
    }

    state.SetItemsProcessed(state.iterations());
}

// 返回第一次匹配成功的索引值
static void Bm_function_Strcspn(benchmark::State &state)
{
    const char test1[] = "openharmony";
    const char test2[] = "bad";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strcspn(test1, test2));
    }

    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Strncpy(benchmark::State &state)
{
    char test1[] = "openharmony";
    char test2[] = "bad";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strncpy(test1, test2, 3));
    }

    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_twoway_strstr(benchmark::State &state)
{
    const char *h = "this is a simple string";
    const char *n = "simple";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strstr(h, n));
    }
    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Strchrnul(benchmark::State &state)
{
    const char *str = "dprtUx";
    int c = 85;
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strchrnul(str, c));
    }
    state.SetItemsProcessed(state.iterations());
}

static void Bm_function_Strcasecmp(benchmark::State &state)
{
    const char *l = "aBcDeD";
    const char *r = "ABCdEd";
    for (auto _ : state)
    {
        benchmark::DoNotOptimize(strcasecmp(l, r));
    }
    state.SetItemsProcessed(state.iterations());
}

MUSL_BENCHMARK(Bm_function_Memmove);
MUSL_BENCHMARK(Bm_function_Strlen);
MUSL_BENCHMARK(Bm_function_Memset);
MUSL_BENCHMARK(Bm_function_Strcmp);
MUSL_BENCHMARK(Bm_function_Memcmp);
MUSL_BENCHMARK(Bm_function_Memchr);
MUSL_BENCHMARK(Bm_function_Strrchr);
MUSL_BENCHMARK(Bm_function_Strnlen);
MUSL_BENCHMARK(Bm_function_Stpncpy);
MUSL_BENCHMARK(Bm_function_Bcmp);
MUSL_BENCHMARK(Bm_function_Strpbrk);
MUSL_BENCHMARK(Bm_function_Strcspn);
MUSL_BENCHMARK(Bm_function_Strncpy);
MUSL_BENCHMARK(Bm_function_twoway_strstr);
MUSL_BENCHMARK(Bm_function_Strchrnul);
MUSL_BENCHMARK(Bm_function_Strcasecmp);